<script setup>
  import * as echarts from 'echarts'
  import { ref, reactive, onMounted, nextTick, watch } from 'vue';
  import { ElMessage, ElMessageBox } from 'element-plus'
  import {
    GetFlexBlock,
    GetFlexBlockVariety,
    GetFlexBlockIndexGroup,
    ExtraFlexIndexData,
  } from '@/api/datlib/datlibFlex'
  import { GetBlob } from '@/utils/dataUtils'
  import { dateInYear } from '@/utils/datetimeUtils'
  import useUserInfoStore  from '@/stores/userinfo'
  const userInfoStore = useUserInfoStore()

  // 数据图形
  const chartOneBox = ref(null)
  const digChartOneBox = ref(null)
  let chartOne = null
  let digChartOne = null

  const varietyTree = ref()
  const indexGroupTable = ref()

  // 指标显示盒子高度
  const indexBox = ref(null)

  const blockBarData = reactive({
    blocks: [],
    currentBlockId: -1,
    refreshLoading: false,
  })
  const blockVarietyData = reactive({
    varieties: [],
    selectVarieties: [],
  })
  const indexData = reactive({
    indexes: [],
    selectIndexes: [],
    currentTab: 'dataTable',
    toggleTabName: '图形',
    extraDataLoading: false,
    downloadDataLoading: false,
    downloadUrl: '',
    tablePage: 1,
    tablePageSize: 500,
    tableData: [],
    sliceStart: 0,
    sliceEnd: 500,
    tableDataHeight: 668,
    tableColumns: [],
    indexCount: 0,
  })

  const digChartData = reactive({
    title: '季节分析',
    isSeason: false,
    isShow: false,
    xAxisDates: dateInYear(2020, false),
    selectMinYear: new Date().getFullYear() - 3,
    viewColumn: null,
  })


  const datatablePageChange = (page) => {
    const s = (page - 1) * indexData.tablePageSize
    const e = s + indexData.tablePageSize
    indexData.sliceStart = s
    indexData.sliceEnd = e
  } 

  const getChartOneOption = () => {
    const checkGroupNames = indexGroupTable.value.getSelectionRows().map((row) => row.index_name)
    let chartSeries = []
    let legendData = []
    const chartData = JSON.parse(JSON.stringify(indexData.tableData)).reverse()
    for (let i=0; i<indexData.tableColumns.length; i++) {
      const seriesCol = indexData.tableColumns[i]
      let seriesObj = {
        type: 'line',
        symbol: 'none',
        connectNulls: true,
        lineStyle: { width: 3 },
        name: seriesCol.label,
        data: chartData.map(j => j[seriesCol.prop])
      }
      chartSeries.push(seriesObj)
      legendData.push({ name: seriesCol.label })
    }

    let opt = {
      title: {
        text: checkGroupNames.join('、'),
        left: 'center'
      },
      grid: {
        bottom: 95,
      },
      legend: {
        left:'center',
        bottom: 45,
        data: legendData
      },
      toolbox: {
        show: true,
        feature: {
          magicType: { 
            type: ['line', 'bar'],
            title: {
                line: '切换为折线图' ,
                bar: '切换为柱状图' ,
                stack: '切换为堆叠' ,
                tiled: '切换为平铺' ,
              }
            },
          restore: {
            title: '还原'
          },
          saveAsImage: {
            title: '保存为图片'
          }
        }
      },
      tooltip: {
        trigger: 'axis',
        showContent: true,
        axisPointer: {
          type: 'cross',
        }
      },
      xAxis: {
        type: 'category',
        data: chartData.map(i => i.datadate)
      },
      yAxis: {
        type: 'value',
        scale: true,
      },
      series: chartSeries,
      dataZoom: [
        {
          type: 'slider',
          start: 60,
          end: 100,
          bottom: 20,
          height: 20
        }
      ],
    } 
    return opt
  }

  const getSeasonChartOption = () => {
    const chartData = JSON.parse(JSON.stringify(indexData.tableData)).slice(1, -1)
    const seriesObj = {}
    const valueKey = digChartData.viewColumn
    for (let i = 0; i < chartData.length; i++ ) {
      const _o = chartData[i]
      const y = _o.datadate.slice(0,4)
      if (seriesObj[y]) {
        seriesObj[y][_o.datadate.slice(5, 10)] = _o[valueKey]
      } else {
        seriesObj[y] = {day: _o.datadate.slice(5, 10), value: _o[valueKey]}
      }
    }
    const seriesData = []
    const legendData = []
    const legendSelected = {}
    const yearList = Object.keys(seriesObj).sort().reverse()
    const currentYear = digChartData.selectMinYear + 3
    for (let y=0; y < yearList.length; y++) {
      const k = yearList[y]
      const yearDataObj = seriesObj[k]
      let line = {
        type: 'line',
        symbol: 'none',
        connectNulls: true,
        lineStyle: { width: 3 },
        name: k,
        zlevel: parseInt(k) === currentYear ? 2 : 0,
        data: digChartData.xAxisDates.map(j => yearDataObj[j])
      }
      seriesData.push(line)
      legendData.push({ name: k })
      legendSelected[k] = parseInt(k) >= digChartData.selectMinYear
    }
    let opt = {
      color: ['#ee6666', '#91cc75', '#fac858', '#5470c6', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
      title: {
        text: digChartData.title,
        left: 'center'
      },
      grid: {
        bottom: 75,
      },
      legend: {
        type: 'scroll',
        left: '10%',
        bottom: 20,
        data: legendData,
        selected: legendSelected,
      },
      toolbox: {
        show: true,
        feature: {
          magicType: { 
            type: ['line', 'bar'],
            title: {
                line: '切换为折线图' ,
                bar: '切换为柱状图' ,
                stack: '切换为堆叠' ,
                tiled: '切换为平铺' ,
              }
            },
          restore: {
            title: '还原'
          },
          saveAsImage: {
            title: '保存为图片'
          }
        }
      },
      tooltip: {
        trigger: 'axis',
        showContent: true,
        axisPointer: {
          type: 'cross',
        }
      },
      xAxis: {
        type: 'category',
        data: digChartData.xAxisDates
      },
      yAxis: {
        type: 'value',
        scale: true,
      },
      series: seriesData,
    }
    return opt
  }

  const toggleDataTabView = () => {
    if (indexData.currentTab === 'dataTable') {
      indexData.currentTab = 'dataCharts'
      indexData.toggleTabName = '数据'
      // console.log('显示图形')
      nextTick(() => {
        if (!chartOne) {
          chartOne = echarts.init(chartOneBox.value) // [指定图形渲染的dom]
        }
        const opt = getChartOneOption()
        chartOne.setOption(opt, { notMerge: true })
      })
    } else {
      indexData.currentTab = 'dataTable'
      indexData.toggleTabName = '图形'
    }
  }

  const extraIndexData = () => {
    const checkVarieyList = getCheckVarietyList()
    const checkGroups = getCheckIndexGroup()
    // console.log(checkVarieyList)
    // console.log(checkGroups)
    if (checkVarieyList.length < 1) {
      ElMessage({
        message: '请至少选择一个品种再提取!',
        type: 'error'
      })
      return
    }
    if (checkVarieyList.length > 10) {
      ElMessageBox({
        message: '一次提取指标过多，请选择少于10个品种的数据!',
        type: 'error',
        title: '错误了'
      })
      return
    }
    if (checkGroups.length < 1) {
      ElMessage({
        message: '请至少选择一个数据再提取!',
        type: 'error'
      })
      return
    }
    if (checkVarieyList.length > 1 && checkGroups.length > 1) {
       ElMessage({
        message: '品种和数据只能指定其中一个多选!',
        type: 'error'
      })
      return
    }
    // 切换显示的tab
    indexData.currentTab = 'dataTable'
    indexData.toggleTabName = '图形'
    indexData.extraDataLoading = true
    ExtraFlexIndexData({
      variety: checkVarieyList,
      groups: checkGroups,
      block_id: blockBarData.currentBlockId
    }).then((res) => {
      const resdata = res.data
      let tableData = resdata.table_data
      let frequencyUnitRow = {
        datadate: '频率,单位',
      }
      for(let i=0; i < resdata.table_columns.length; i++) {
          const _o = resdata.table_columns[i]
          frequencyUnitRow[_o.prop] = `${_o.frequency},${_o.unit}`
      }
      tableData.unshift(frequencyUnitRow)
      indexData.tableData = tableData
      indexData.tableColumns = resdata.table_columns
      indexData.downloadUrl = resdata.tmp_file
      indexData.extraDataLoading = false
      if (indexData.tableData.length < 1) {
        ElMessage({
          message: '提取的结果没有数据!',
          type: 'info'
        })
      }
    }).catch(() => {
      indexData.extraDataLoading = false
    })
  }

  const downloadData = () => {
    if (indexData.tableData.length < 1 || !indexData.downloadUrl) {
      ElMessage({
        message: '请先提取数据...',
        type: 'error'
      })
      return
    }
    indexData.downloadDataLoading = true
    GetBlob(indexData.downloadUrl).then((blob) => {
      let a = document.createElement('a')
      a.href = window.URL.createObjectURL(blob)
      a.target = '_blank'
      // a.download = this.currentRow.annexName
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      indexData.downloadDataLoading = false
    }).catch(() => {
      indexData.downloadDataLoading = false
    })
  }

  const viewDataCharts = () => {
    if (indexData.tableColumns.length < 1) {
      ElMessage({
        message: '请先提取数据后再可视化图形',
        type: 'error'
      })
      return
    }
    digChartData.isSeason = false
    digChartData.title = '数据可视化'
    digChartData.isShow = true
    nextTick(() => {
      if (!digChartOne) {
        digChartOne = echarts.init(digChartOneBox.value) // [指定图形渲染的dom]
      }
      const opt = getChartOneOption()
      digChartOne.setOption(opt, { notMerge: true })
    })
  }

  const viewSeasonCharts = () => {
    if (indexData.tableColumns.length < 1) {
      ElMessage({
        message: '请先提取数据后再进行分析',
        type: 'error'
      })
      return
    }
    if (!digChartData.viewColumn) {
      digChartData.viewColumn = 'col_0'  // 之后watch逻辑将再次调用
      return
    }
    for (let i = 0; i < indexData.tableColumns.length; i ++) {
      let col = indexData.tableColumns[i]
      if (col.prop === digChartData.viewColumn) {
        digChartData.title = col.label
        break
      }
    }
    digChartData.isSeason = true
    digChartData.isShow = true
    const opt = getSeasonChartOption()
    nextTick(() => {
      if (!digChartOne) {
        digChartOne = echarts.init(digChartOneBox.value) // [指定图形渲染的dom]
      }
      digChartOne.setOption(opt, { notMerge: true })
    })
  }

  // 获取选中的品种
  const getCheckVarietyList = () => {
    const checkList =  varietyTree.value.getCheckedNodes().filter((node) => {
      return node.is_real
    })
    return checkList.map((v) => v.code)
  }

  // 获取选中的指标组
  const getCheckIndexGroup = () => {
    return indexGroupTable.value.getSelectionRows().map((row) => row.block_group_id)
  }

  // 顶部刷新
  const toHeaderFresh = () => {
    console.log(getCheckVarietyList())
    if (blockBarData.refreshLoading) return
    mountedInitial()
  }

  // 设置数据table高度
  const setDataTableHeight = () => {
    nextTick(() => {
      if (indexBox.value) {
        const indexHeight = indexBox.value.clientHeight
        const docHeight = document.documentElement.clientHeight
        // console.log(docHeight, indexHeight)
        // console.log(docHeight -  98 - indexHeight)
        indexData.tableDataHeight = docHeight -  129 - indexHeight
      }
    })
  }

  // mounted INIT
  const mountedInitial = () => {
    // 定制板块
    blockBarData.refreshLoading = true
    GetFlexBlock().then((res) => {
      blockBarData.blocks = res.data.blocks
      blockBarData.refreshLoading = false
      if (blockBarData.blocks.length > 0) {
        blockBarData.refreshLoading = true
        const blockId = blockBarData.blocks[0].flex_block_id
        blockBarData.currentBlockId = blockId
        GetFlexBlockVariety(blockId).then((res) => {
          blockVarietyData.varieties = res.data.variety
          blockBarData.refreshLoading = false
          if (blockVarietyData.varieties.length > 0) {
            // 有定制品种才获取板块下的定制指标
            blockBarData.refreshLoading = true
            GetFlexBlockIndexGroup(blockId).then((res) => {
              indexData.indexes = res.data.index_groups
              blockBarData.refreshLoading = false
              setDataTableHeight()
            })
          }
        })
      }
    })
  }
  
  const extraIndexSelectChange = () => {
    const selectVarietyList = getCheckVarietyList()
    const selectIndexList = getCheckIndexGroup()
    if (selectVarietyList.length > 1 && selectIndexList.length > 1) return
    indexData.indexCount = parseInt(selectVarietyList.length * selectIndexList.length)
  }

  watch(() => digChartData.viewColumn, (n) => {
    if (!n) return
    viewSeasonCharts()
  }, {immediate: true})

  onMounted(() => {
    mountedInitial()
  })
</script>
<template>
  <div class="page-container">
    <div class="block-bar">
      <div
        v-for="b in blockBarData.blocks"
        :key="b.id"
        class="block-item"
      >
        {{ b.block_name }}
      </div>
      <div :class="blockBarData.refreshLoading ? 'header-refresh-loading' : 'header-refresh'">
        <el-icon @click="toHeaderFresh">
          <Refresh />
        </el-icon>
      </div>
    </div>
    <div class="page-content">
      <div class="left-pane">
        <el-scrollbar>
          <el-tree
            ref="varietyTree"
            show-checkbox
            node-key="code"
            empty-text="暂无定制品种"
            :data="blockVarietyData.varieties"
            :props="{label:'name'}"
            @check-change="extraIndexSelectChange"
          />
        </el-scrollbar>
      </div>
      <div class="right-pane">
        <div ref="indexBox">
          <!-- 高度272刚好容下10个指标量 -->
          <el-table
            stripe
            max-height="272"
            row-class-name="table-row"
            ref="indexGroupTable"
            empty-text="暂无定制指标"
            :data="indexData.indexes"
            @selection-change="extraIndexSelectChange"
          >
            <el-table-column type="selection" width="25" />
            <el-table-column prop="index_name" label="名称" />
            <el-table-column prop="frequency" label='频率' width="90" />
            <el-table-column prop="flex_type" label="定制方式" width="130" />
            <el-table-column prop="active_expire" label="有效期" width="90" />
          </el-table>
        </div>
        <div class="data-actions">
          <el-button
            plain
            type="primary"
            :loading="indexData.extraDataLoading"
            @click="extraIndexData"
          >
            提取数据<span v-if="indexData.indexCount > 0">({{ indexData.indexCount }})</span>
          </el-button>
          <el-button
            plain
            type="primary"
            @click="viewDataCharts"
          >
            可视化绘图
          </el-button>
          <el-button
            plain
            type="primary"
            @click="viewSeasonCharts"
          >
            季节分析
          </el-button>
          <el-button
            v-if="userInfoStore.isVip"
            plain
            type="primary"
            :disabled="!indexData.downloadUrl"
            :loading="indexData.downloadDataLoading"
            @click="downloadData"
          >
            下载数据
          </el-button>
          <div class="data-actions-right">
            <el-button
              plain
              type="primary"
              icon="Switch"
              @click="toggleDataTabView"
            >
              {{ indexData.toggleTabName }}
            </el-button>
          </div>
        </div>
        <!-- 显示数据 -->
        <div class="data-tabs">
          <el-tabs v-model="indexData.currentTab">
            <el-tab-pane label="数据" name="dataTable">
              <el-table
                stripe
                highlight-current-row
                :height="indexData.tableDataHeight"
                :data="indexData.tableData.slice(indexData.sliceStart, indexData.sliceEnd)"
              >
                <el-table-column prop="datadate" label="日期" width="100" />
                <el-table-column
                  v-for="col in indexData.tableColumns"
                  :key="col.prop"
                  :label="col.label"
                  :prop="col.prop"
                />
              </el-table>
              <el-pagination
                small
                background
                layout="total,prev,pager,next,jumper"
                class="table-pagination"
                :page-size="indexData.tablePageSize"
                :total="indexData.tableData.length"
                @current-change="datatablePageChange"
              />
            </el-tab-pane>
            <el-tab-pane label="图形" name="dataCharts">
              <div class="chart-pane">
                <div ref="chartOneBox" class="data-chart"></div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </div>
    <div class="chart-dialog">
    <el-dialog
      v-model="digChartData.isShow"
      draggable
      width="820"
      :modal="false"
      :close-on-click-modal="false"
      :title="digChartData.title"
    >
      <template #header>
        <div class="header-box">
          <el-select
            v-show="digChartData.isSeason"
            v-model="digChartData.viewColumn"
            placeholder="选择一列数据用于季节分析"
          >
            <el-option
              v-for="c in indexData.tableColumns"
              :key="c.prop"
              :value="c.prop"
              :label="c.label"
            />
          </el-select>
        </div>
      </template>
      <div ref="digChartOneBox" class="dig-chart"></div>
    </el-dialog>
    </div>
  </div>
</template>
<style scoped lang="scss">
  @keyframes refreshspin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(-360deg); }
  }
  .page-container {
    .block-bar {
      line-height: 28px;
      height: 28px;
      display: flex;
      align-items: center;
      background-color: #eee;
      .block-item {
        margin-left: 10px;
        font-size: 14px;
        cursor: pointer;
        user-select: none;
        &:hover {
          color: #ea5404;
        }
      }
      .header-refresh {
        display: flex;
        align-items: center;
        margin-left: auto;
        margin-right: 10px;
        cursor: pointer;
        &-loading {
          margin-left: auto;
          margin-right: 10px;
          align-items: center;
          display: flex;
          animation: refreshspin 2s linear infinite;
        }
      }
    }
    .page-content {
      display: flex;
      .left-pane {
        border: 1px solid #eeeeee;
        border-top: 0;
        min-width: 258px;
        width: 258px;
        height: calc(100vh - 69px); /* 40menuBar+28blockBar+1pxborderbottom */
        min-height: calc(100vh - 69px);
        background-color: #fff;
      }
      .right-pane {
        width: calc(#{$content-width} - 261px); /** 1pxborder-right */
        min-width: calc(#{$content-width} - 261px);
        border-right: 1px solid #eeeeee;
        border-bottom: 1px solid #eeeeee;
        // height: calc(100vh - 68px);
        // min-height: calc(100vh - 68px);
        background-color: #fff;
        .data-actions {
          height: 30px;
          display: flex;
          align-items: center;
          padding-left: 10px;
          background: linear-gradient(to bottom,#eee,#fff, #eee);
          .data-actions-right{
            margin-left: auto;
          }
          ::v-deep(.el-button) {
            margin-left: 0;
            padding: 5px 7px;
            border:none;
            color: #222;
            background-color: rgba(238, 238, 200, 0);
            &:focus-visible {
              outline: 0;
            }
            &:hover {
              color: $goldenColor;
            }
          }
        }
        .data-tabs {
          .el-tabs ::v-deep(.el-tabs__header) {
            display:none;
          }
          .data-table {
            max-height: calc(100vh - 300px);
          }
          .table-pagination {
            height: 24px;
            margin: 3px 10px;
          }
          .chart-pane {
            padding-top: 16px;
            .data-chart {
              width: 1140px;
              height: 550px;
            }
          }
        }
        .el-table ::v-deep(.table-row) {
          font-size: 13px;
          color: #222;
        }
      }
    }
    .chart-dialog {
      pointer-events: none;
      ::v-deep(.el-dialog__header) {
        padding: 0;
        margin-right:0;
      }
      ::v-deep(.el-dialog__headerbtn) {
        height: 40px;
      }
      ::v-deep(.el-input__wrapper){
        border-radius: 0;
        box-shadow: 0 0 0 0 !important;
        background-color: #d2dffa;
        &:hover {
          box-shadow: 0 0 0 0;
        
        }
      }
      .header-box {
        border-bottom: 1px solid #efefef;
        background-color: #dce5f8;
        height: 40px;
        line-height: 40px;
        padding-left: 20px;
      }
      .dig-chart {
        width: 780px;
        height: 400px;
      }
      ::v-deep(.el-dialog) {
        pointer-events: auto;
      } 
    }
  }
</style>